<script setup lang="ts">
import { defineProps, defineEmits, ref, onMounted, onUnmounted, defineExpose, watch } from 'vue'
import EasyMDE, { Options } from 'easymde'
// 类型，属性及事件
interface EditorProps {
  modelValue?: string
  options?: Options
}
interface EditorEvents {
  (type: 'update:modelValue', value: string): void
  (type: 'change', value: string): void
  (type: 'blur'): void
}

const props = defineProps<EditorProps>()

const emit = defineEmits<EditorEvents>()
// 有了模板我们需要一些初始的数据
// 1 暴露对应的方法
// 2 结合页面实现验证功能
const textArea = ref<null | HTMLTextAreaElement>(null)
let easyMDEInstance: EasyMDE | null = null
const innerValue = ref(props.modelValue || '')

watch(() => props.modelValue, (newVal) => {
  if (easyMDEInstance) {
    if (newVal !== innerValue.value) {
      easyMDEInstance.value(newVal || '')
    }
  }
})

onMounted(() => {
  if (textArea.value) {
    // 组装 options
    const config: Options = {
      ...(props.options || {}),
      element: textArea.value,
      initialValue: innerValue.value
    }
    easyMDEInstance = new EasyMDE(config)
    // 监控对应的事件
    easyMDEInstance.codemirror.on('change', () => {
      if (easyMDEInstance) {
        // 拿到当前的值
        const updateValue = easyMDEInstance.value()
        innerValue.value = updateValue
        emit('update:modelValue', updateValue)
        emit('change', updateValue)
      }
    })
    easyMDEInstance.codemirror.on('blur', () => {
      if (easyMDEInstance) {
        emit('blur')
      }
    })
  }
})

// 销毁对应的实例
onUnmounted(() => {
  if (easyMDEInstance) {
    easyMDEInstance.cleanup()
  }
  easyMDEInstance = null
})

const clear = () => {
  if (easyMDEInstance) {
    easyMDEInstance.value('')
  }
}

const getMDEInstance = () => {
  return easyMDEInstance
}

defineExpose({
  clear, getMDEInstance
})
</script>

<template>
<div class="vue-easymde-editor">
  <textarea ref="textArea"></textarea>
</div>
</template>

<style scoped>
.vue-easymde-editor.is-invalid {
  border: 1px solid #dc3545;
}
</style>
